
package com.trydofor.id.exec;

import java.util.Map;
import java.util.Map.Entry;

import com.trydofor.aloe.exception.Exceptions;
import com.trydofor.id.doer.shell.ArgChecker;
import com.trydofor.id.doer.shell.Command;
import com.trydofor.id.doer.shell.Executer;
import com.trydofor.id.doer.shell.Outcome;
import com.trydofor.id.logs.Eventer;
import com.trydofor.id.logs.Eventer.Event;
import com.trydofor.id.logs.LogLevel;

/**
 * @author : Shi Rongjiu (www.trydofor.com)
 */
public class EventerExe implements Executer {
    
    private final Command cmdAll;
    private final Command cmdSet;
    private final Eventer eventer;
    
    /**
     * constructor
     * 
     * @param eventer the eventer
     * @throws NullPointerException if eventer is null
     */
    public EventerExe(Eventer eventer) {
        Exceptions.checkNullPointer(eventer);
        this.eventer = eventer;
        this.cmdAll = EventerCmd.listEventer();
        this.cmdSet = EventerCmd.changeEventer(eventer);
    }
    
    /**
     * {@inheritDoc}
     */
    public Outcome execute(Command command, Map<String, String> argdata) {
        
        String err = ArgChecker.check(command, argdata);
        if (err != null) return new Outcome(-1, null, err);
        
        if (cmdAll.getAlias().equals(command.getAlias())) {
            return listAll(command, argdata);
        }
        else if (cmdSet.getAlias().equals(command.getAlias())) {
            return change(command, argdata);
        }
        return new Outcome(-1, null, "Command is unsupported:" + command);
    }
    
    // ------------------
    private Outcome listAll(Command command, Map<String, String> argdata) {
        Map<Event, LogLevel> el = eventer.copyEventLevels();
        StringBuilder sb = new StringBuilder();
        for (Entry<Event, LogLevel> e : el.entrySet()) {
            sb.append(Eventer.toFullName(e.getKey()));
            sb.append("=");
            sb.append(e.getValue().name());
            sb.append('\n');
        }
        
        return new Outcome(0, sb.toString(), null);
    }
    
    private Outcome change(Command command, Map<String, String> argdata) {
        int status = 0;
        String output = null;
        String errput = null;
        
        String event = argdata.get("event");
        String level = argdata.get("level");
        LogLevel lgl = LogLevel.valueOf(level);
        if (lgl == null) {
            status = -1;
            errput = "level not found, level=" + level;
        }
        else {
            Event evt = null;
            Map<Event, LogLevel> el = eventer.copyEventLevels();
            for (Event ev : el.keySet()) {
                String key = Eventer.toFullName(ev);
                if (key.equals(event)) {
                    evt = ev;
                    break;
                }
            }
            if (evt == null) {
                status = -2;
                errput = "event not found, event=" + event;
            }
            else {
                LogLevel old = eventer.register(evt, lgl);
                status = 0;
                output = "change event[" + event + "] from " + old + " to " + level;
            }
        }
        
        return new Outcome(status, output, errput);
    }
}
